import { Module, MiddlewareConsumer } from '@nestjs/common'
import { APP_GUARD, APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core'
import { TypeOrmModule } from '@nestjs/typeorm'
import { AppController } from '@/app.controller'
import { AppService } from '@/app.service'
import { RouterModule } from '@/router/router.module'
import { UserModule } from '@/user/user.module'
import { RoleModule } from '@/role/role.module'
import { AvatarModule } from '@/avatar/avatar.module'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { ServeStaticModule } from '@nestjs/serve-static'
import { JwtModule } from '@nestjs/jwt'
import { PublicGuard } from '@/guard/public.guard'
import { HttpExceptionFilter } from '@/common/errorHandling.interceptor'
import { utilities as nestWinstonModuleUtilities, WinstonModule, WinstonModuleOptions } from 'nest-winston'
import { LoggerMiddleware } from '@/middleware/logger.middleware'
import { TransformResponseInterceptor } from '@/common/transformResponse.interceptor'
import { CodeModule } from './code/code.module'
import 'winston-daily-rotate-file'
import * as winston from 'winston'
import * as path from 'path'

type DatabaseType = 'mysql' | 'mariadb' | 'postgres' | 'sqlite' | 'oracle' | 'mssql'

@Module({
  imports: [
    // 指定静态资源目录
    ServeStaticModule.forRoot({
      rootPath: path.join(__dirname, '..', 'public')
    }),
    // 全局环境变量配置
    ConfigModule.forRoot({
      envFilePath: [
        path.resolve(__dirname, '..', '.env'), // 默认环境文件
        path.resolve(__dirname, '..', `.env.${process.env.NODE_ENV}`) // 根据 NODE_ENV 加载环境配置
      ],
      isGlobal: true // 配置项全局可用
    }),
    // 日志模块配置
    WinstonModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        // 日志输出的管道
        const transportsList: WinstonModuleOptions['transports'] = [
          new winston.transports.DailyRotateFile({
            level: 'error',
            dirname: `logs`,
            filename: `%DATE%-error.log`,
            datePattern: 'YYYY-MM-DD',
            maxSize: '20m'
          }),
          new winston.transports.DailyRotateFile({
            dirname: `logs`,
            filename: `%DATE%-combined.log`,
            datePattern: 'YYYY-MM-DD',
            maxSize: '20m',
            format: winston.format.combine(
              winston.format((info) => {
                if (info.level === 'error') return false // 过滤掉'error'级别的日志
                return info
              })()
            )
          }),
          new winston.transports.Console({
            format: winston.format.combine(
              winston.format.timestamp(),
              winston.format.ms(),
              nestWinstonModuleUtilities.format.nestLike(config.get<string>('SERVER_TITLE'), {
                colors: true,
                prettyPrint: false,
                processId: false,
                appName: true
              })
            )
          })
        ]
        return {
          transports: transportsList
        }
      }
    }),
    // 数据库连接
    TypeOrmModule.forRootAsync({
      useFactory: (config: ConfigService) => {
        return {
          type: config.get<DatabaseType>('DB_TYPE'),
          username: config.get<string>('DB_USER'),
          password: config.get<string>('DB_PASSWORD'),
          host: config.get<string>('DB_HOST'),
          port: +config.get<string>('DB_PORT'),
          database: config.get<string>('DB_NAME'),
          synchronize: process.env.NODE_ENV != 'prod',
          retryDelay: 500,
          retryAttempts: 10,
          autoLoadEntities: true
        }
      },
      inject: [ConfigService]
    }),
    // JWT 配置
    JwtModule.registerAsync({
      global: true,
      imports: [ConfigModule],
      useFactory: async (config: ConfigService) => {
        return {
          secret: config.get<string>('JWT_SECRET'),
          signOptions: {
            expiresIn: config.get<string>('JWT_EXP')
          }
        }
      },
      inject: [ConfigService]
    }),
    RouterModule,
    UserModule,
    RoleModule,
    AvatarModule,
    CodeModule
  ],
  controllers: [AppController],
  providers: [
    AppService,
    // 全局守卫，验证 token
    {
      provide: APP_GUARD,
      useClass: PublicGuard
    },
    // 全局过滤器，统一处理错误
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter
    },
    // 全局拦截器，统一处理响应
    {
      provide: APP_INTERCEPTOR,
      useClass: TransformResponseInterceptor
    }
  ]
})
export class AppModule {
  // 全局中间件，记录请求日志
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*')
  }
}
